/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "ui文本页面.h"
#include "../ui属性栏.h"

#include <JIT.h>
#include <UI/布局.h>

#include <节点/逻辑/单节点脚本.h>



static uint16 g页面绘制属性ID = 0;
static S_单色绘制ID g页面背景ID = {};

static ui_绘制模板_块文本绘制	g行号绘制;
static ui_绘制工具_滚动条		g滚动条绘制;
static C_状态条* g文本视口主状态条 = nullptr;


static void f_on_文本页面绘制(C_Widget* self, S_2D画布* 画布) {
	C_文本框* box = dynamic_cast<C_文本框*>(f_ui_get滚动框视口(self));
	return;

	g页面绘制属性ID = f_vg_gen属性(画布);

	f_vg_set属性(画布, g页面绘制属性ID, { 1,1 }, { 0,0 }, 0, 2);
	{
		//g页面背景ID.id_变换 = f_vg_gen变换(画布);
		//g页面背景ID.id_颜色 = f_vg_gen颜色(画布);
		auto p = f_vg_gen属性(画布);

		//auto pen = f_vg_gen单色填充(画布, g页面背景ID.id_变换, g页面背景ID.id_颜色, g页面绘制属性ID);
		f_vg_set单色(画布, g页面背景ID.id_颜色, 0, S_UI主题::uic_行编辑框背景);
		//g页面背景ID.id_元素 = f_vg_绘制矩形(画布, pen, { 0.0f, 0.0f, 1.0f, 1.0f }, true);
		f_vg_set实例数量(画布, 0, 1);
	}


	g行号绘制.f_Draw点(画布, self->m_UIctx->m_文字字号, *(box->m_字体), g页面绘制属性ID);
	g滚动条绘制.f_Draw点(画布, g页面绘制属性ID);

}

static void f_on_文本页面布局(C_Widget* self, C_Widget** son, uint32 num) {
	//son[2]->f_setSize(self->m_Size);
	f_布局_双向滚动条(self, E_方向::e_纵向, 3);
	f_布局_双向滚动条(self, E_方向::e_横向, 3);
}

static void f_on_文本页面修改(C_Widget* self) {
	auto* box = f_ui_from滚动框取文本视口(self);

	mat3X2 mat;
	mat.row0 = self->m_Pos;
	mat.row1 = self->m_Size;
	mat.row2 = { 1,0 };
	f_vg_set变换(self->m_画布, g页面背景ID.id_变换, 0, mat);


	S_文档文本* doc = f_ui_get文档数据(self);
	vec2 pos = box->m_文本对齐偏移 + box->m_Pos;
	
	uint32 字符数量 = f_ui_get文档文本总字符数(*doc);
	auto& t = g行号绘制.f_GPU参数修改_begin(self->m_画布, 字符数量, doc->m_文本块.size());
	g行号绘制.f_填充文本(self->m_画布, *doc, pos, *(box->m_字体), box->m_字行距);
	g行号绘制.f_GPU参数修改_end(self->m_画布);


	auto e = self->f_get更新部件();
	self->m_GPU参数重置 |= g滚动条绘制.f_alloc(self->m_画布, 2, S_UI主题::ui_滚动条厚度 * self->m_UIctx->m_DPI);
	g滚动条绘制.f_set(self->m_画布, e.m_W[1], 0);
	g滚动条绘制.f_set(self->m_画布, e.m_W[2], 1);
	g滚动条绘制.f_End(self->m_画布);


	g行号绘制.f_框选(self->m_画布, box);


	if (t.GPU参数重置) {
		self->m_GPU参数重置 = true;
	}
}




/*static bool on_文本页面开启编辑(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_属性栏视口* 属性面板 = dynamic_cast<C_属性栏视口*>(self->m_父部件->m_父部件);
	属性面板->m_vec编辑_绘制模板.f_开启编辑(属性面板->m_画布, self, 字体);

	属性面板->m_GPU参数重置 = true;
	return true;
}*/
static void on_文本页面当前输入(C_Widget* self, std::wstring& text) {
	C_文本框* editBox = dynamic_cast<C_文本框*>(self);
	//C_属性栏视口* 属性面板 = dynamic_cast<C_属性栏视口*>(self->m_父部件->m_父部件);
	//g行号绘制.f_当前输入(属性面板->m_画布, *self, 字体, text);
	//g行号绘制.f_输入(self->m_父部件->m_画布, (C_文本框*)self, text);
	//g行号绘制.f_输入(self->m_画布, (C_文本框*)self, text);

	auto 前后字符 = editBox->f_get当前输入前后字符();
	if (text == L"{") {
		editBox->f_插入字符(L'}', editBox->m_光标);
	}
	else if (text == L"[") {
		editBox->f_插入字符(L']', editBox->m_光标);
	}
	else if (text == L"\n") {
		uint32 num = 0;
		if (editBox->f_get行头字符(editBox->m_光标.y - 1) == '\t') {
			num = editBox->f_get同样字符数量(editBox->m_光标.y - 1, 0, '\t');
		}
		
		if (前后字符.前 == '[' && 前后字符.后 == ']') {
			goto To_括号自动补全;
		}
		if (前后字符.前 == '{' && 前后字符.后 == '}') {
			To_括号自动补全:
			editBox->f_插入行(editBox->m_光标.y);

			for (uint32 i = 0; i < num; ++i) {
				editBox->f_插入字符(L'\t', { 0, editBox->m_光标.y + 1 });
			}

			++num;
		}

		for (uint32 i = 0; i < num; ++i) {
			editBox->f_插入字符(L'\t', editBox->m_光标);
			++editBox->m_光标.x;
		}

	}

	self->m_GPU参数重置 = true;
}

static void on_文本页面输入完成(C_Widget* self) {
	//C_属性栏视口* 属性面板 = dynamic_cast<C_属性栏视口*>(self->m_父部件->m_父部件);
	//auto* box = f_ui_from滚动框取文本视口(self);
	g行号绘制.f_输入完成(self->m_画布, (C_文本框*)self);
	//if (属性面板->mf_外部部件更新) {
	//	属性面板->mf_外部部件更新(属性面板->m_外部绑定部件);
	//}
	//self->m_绘制属性更新 = true;
	self->m_GPU参数重置 = true;
}

static bool on_文本框鼠标点击(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_文本框* editBox = dynamic_cast<C_文本框*>(self);

	if (C_文本框::g当前操作文本框 && C_文本框::g当前操作文本框 != editBox) {
		C_文本框::g当前操作文本框->f_输入完成();
	}

	C_文本框::g当前操作文本框 = editBox;
	editBox->f_开启输入();

	
	editBox->f_set光标();
	editBox->m_选取.开始行列 = { int32(editBox->m_光标.x) + 1, int32(editBox->m_光标.y) };
	editBox->m_选取.结束行列 = editBox->m_选取.开始行列;
	//editBox->m_绘制属性更新 = true;
	//editBox->m_GPU参数重置 = true;
	//g行号绘制.f_输入完成(self->m_父部件->m_画布, editBox);
	g行号绘制.f_输入完成(self->m_画布, editBox);
	
	self->m_父部件->m_绘制属性更新 = true;
	return true;
}

static void on_框选时(C_Widget* self) {
	//C_属性栏视口* 属性面板 = dynamic_cast<C_属性栏视口*>(self->m_父部件->m_父部件);
	g行号绘制.f_框选(self->m_父部件->m_画布, (C_文本框*)self);
	self->m_父部件->m_GPU参数重置 = true;
}
static void on_框选后(C_Widget* self) {
	//C_属性栏视口* 属性面板 = dynamic_cast<C_属性栏视口*>(self->m_父部件->m_父部件);
	g行号绘制.f_框选(self->m_父部件->m_画布, (C_文本框*)self);
}


static void on_编译(S_结构对象指针 obj) {
	auto code = f_文档转字符串(*f_ui_get文档数据((C_Widget*)obj));

	auto* 脚本节点 = dynamic_cast<C_函数节点*>(f_global_get激活节点后端());
	if (脚本节点) {
		//f_JIT_编译代码(脚本节点->m_程序集, code);
		//脚本节点->f_编译();
		S_框架::gfu_更新选择节点();
	}

	//f_页面_更新联动工作区(0);
}



void on_文本编辑视口联动更新(C_工作区页面* 工作区) {
	auto* 脚本节点 = dynamic_cast<C_函数节点*>(f_global_get激活节点后端());
	//auto node = f_global_get激活节点后端();
	auto& 节点名称 = f_prop_enum(工作区->m_状态条->f_getProp(2));
	//f_页面_从节点工作区更新其他工作区();

	if (脚本节点) {
		//节点名称.m_Names[0] = 脚本节点->f_getWName();
		//f_ui_bind文本编辑框文档(工作区->mui_主页面, &脚本节点->m_代码);
		//工作区->mui_画布页面->m_绘制属性更新 = true;

	}

	工作区->m_状态条->m_绘制属性更新 = true;
}



C_工作区页面* f_工作区_创建文本编辑视口(S_UI创建环境& ctx) {
	auto* ui_edit = f_ui_创建编辑框(ctx, on_文本页面当前输入, on_文本页面输入完成, S_节点UI主题::ui_默认字体);

	C_状态条* 状态条 = new C_状态条(ctx);
	C_工作区页面* 工作区 = new C_工作区页面(E_工作区类型::e_文本编辑视口, ctx, E_方向::e_横向, ui_edit, 状态条);
	
	if (g文本视口主状态条 == nullptr) {
		g文本视口主状态条 = 状态条;
	}

	{
		std::vector<S_Props> props;
		auto 编译按钮 = f_alloc_OpsProp(on_编译, (S_结构对象指针)ui_edit, L"编译");
		props.push_back(编译按钮);
		props.push_back(f_alloc_NoneProp());
		props.push_back(f_alloc_EnumProp(nullptr, { {L"节点",""}, {L"节点1",""} }, L"", 0, nullptr, false));
		props.push_back(f_alloc_NoneProp());

		状态条->f_构建属性部件(props, g文本视口主状态条);
	}

	ui_edit->mf_DrawFun = f_on_文本页面绘制;
	//ui_edit->mf_布局Fun = f_on_文本页面布局;
	ui_edit->mf_变换修改 = f_on_文本页面修改;
	f_ui_get滚动框视口(ui_edit)->mf_鼠标按键点击 = on_文本框鼠标点击;

	f_ui_set文本框框选回调(f_ui_from滚动框取文本视口(ui_edit), on_框选时, on_框选后);
	f_页面_绑定工作区更新回调(E_工作区类型::e_文本编辑视口, on_文本编辑视口联动更新, 工作区);

	return 工作区;
}

void f_文本编辑视口_更新()
{

}


